﻿using System;
using System.Drawing;
using System.IO;
using System.Net;
using MapCenterSystem.DataAccess;
using MapCenterSystem.Utility;
using MapCenterSystem.DataInfo;

namespace MapCenterSystem.ServiceProvider.GoogleMap
{
    
    public class GoogleMapProvider : MapProviderService
    {
        private string server = "mt";
        private string request = "vt";//
        private string lyrs = "m@114";//version
        private string hl = "vi";// language 
        private Image[,] image = new Image[3, 3];

        private int GetServerResponse(Point tile, int max)
        {
            return (tile.X + 2 * tile.Y) % max;
        }

        private byte[] GetGoogleMap(MapInfo map)
        {
            if (map.Exist())
                return map.ConvertToByte();
            #region old
            //string url = string.Format("http://{0}{1}.google.com/{2}/lyrs={3}&hl={4}&src=api&x={5}&y={6}&z={7}&s=",
            //                server, GetServerResponse(map.Tile, 4), request, lyrs, hl, map.Tile.X, map.Tile.Y, map.Zoom);
            //WebRequest webrequest = WebRequest.Create(url);
            //((HttpWebRequest)webrequest).UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5";
            //WebResponse webresponse = webrequest.GetResponse();
            //Stream stream = webresponse.GetResponseStream();
            //StreamReader streamReader = new StreamReader(stream);
            //MemoryStream memStream = new MemoryStream();
            //byte[] respBuffer = new byte[1024];
            //int byteRead = stream.Read(respBuffer, 0, respBuffer.Length);
            //while (byteRead > 0)
            //{
            //    memStream.Write(respBuffer, 0, byteRead);
            //    byteRead = stream.Read(respBuffer, 0, respBuffer.Length);
            //}
            //return memStream.GetBuffer();
#endregion
            return null;
        }

        private void InitListImage(MapInfo map)
        {
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    Point currentTile = new Point(map.Tile.X + i, map.Tile.Y + j);
                    MapInfo mapTemp = new MapInfo();
                    mapTemp.EarthPoint = map.EarthPoint;
                    mapTemp.MapStore = map.MapStore;
                    mapTemp.Size = map.Size;
                    mapTemp.Source = map.Source;
                    mapTemp.Zoom = map.Zoom;
                    mapTemp.Tile = currentTile;
                    Image temp = map.GetMapFromByte(GetGoogleMap(mapTemp));
                    if(!mapTemp.Exist())
                        mapTemp.SaveImage(temp);
                    temp.Dispose();
                    image[i, j] = new Bitmap(mapTemp.FullPath);
                }
            }
        }

        //Ghep hinh 
        private Image CombineImage()
        {
            Image memImage = new Bitmap(3 * 256, 3 * 256);
            Graphics g = Graphics.FromImage(memImage);
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    g.DrawImage(image[i, j], i * 256, j * 256);
                }
            }
            g.Dispose();
            return memImage;
        }

        //Lay hinh ra
        public override byte[] GetMap(MapInfo map)
        {
            map.MapStore = Path.Combine(map.MapStore, "Google");
            map.GetTileFromEarthPoint();
            Point startPoint = map.TileStartPoint;
            Point distantTwoPoint = new Point();
            distantTwoPoint.X = Math.Abs(map.EarthPoint.X - startPoint.X);
            distantTwoPoint.Y= Math.Abs(map.EarthPoint.Y- startPoint.Y);
            InitListImage(map);
            Image memImage = CombineImage();
            Image currentImage = new Bitmap(map.Size.Width, map.Size.Height);
            Graphics g = Graphics.FromImage(currentImage);
            g.DrawImage(memImage, new Rectangle(0, 0, currentImage.Width, currentImage.Height),
                new Rectangle(distantTwoPoint.X, distantTwoPoint.Y, currentImage.Width, currentImage.Height), GraphicsUnit.Pixel);
            g.Dispose();
            return map.ConvertToByte(currentImage);
        }

        public override void Dispose()
        {
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    image[i, j].Dispose();
                }
            }
        }
    }
}
